<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Minio测试前端直传</title>
    <script src="js/vue.js"></script>
    <script src="js/jquery.js"></script>
</head>
<body>
<div id="app">
    <form @submit.prevent="uploadFile">
        <label>
            文件
            <input id="file" type="file" @change="fileChange">
        </label>
        <br><br>
        <button type="submit" v-show="file != null">上传文件</button>
    </form>
    <p v-if="uploadStatus">{{ uploadStatus }}</p>
</div>

<script>
    var vm = new Vue({
        el: "#app",
        data() {
            return {
                file: null,
                uploadStatus: ""
            };
        },
        methods: {
            /**
             * 选择文件
             */
            fileChange(event) {
                this.file = event.target.files[0];
                this.uploadStatus = "";
            },
            /**
             * 获取预签名表单数据
             */
            getPresignedFormData(fileName, fileType) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: 'http://localhost:9989/oss/presign/form',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({
                            bucketName: "demo",
                            fileName: fileName,
                            type: fileType
                        }),
                        success: (response) => resolve(response),
                        error: (xhr, status, error) => reject(new Error("无法获取预签名数据"))
                    });
                });
            },
            /**
             * 上传文件
             */
            async uploadFile() {
                if (!this.file) {
                    alert('请选择一个文件');
                    return;
                }

                try {
                    this.uploadStatus = "正在获取预签名数据...";
                    const presignedData = await this.getPresignedFormData(this.file.name, this.file.type);

                    this.uploadStatus = "正在上传文件...";
                    await this.putObject(presignedData);

                    this.uploadStatus = "上传成功";
                    alert("文件上传成功");
                } catch (error) {
                    console.error('上传失败:', error);
                    this.uploadStatus = "上传失败，请重试";
                    alert(`上传失败: ${error.message}`);
                }
            },
            /**
             * 上传单个文件
             */
            putObject(presignedData) {
                return new Promise((resolve, reject) => {
                    // 构建带有预签名参数的完整 URL
                    const urlParams = new URLSearchParams({
                        'x-amz-algorithm': presignedData['x-amz-algorithm'],
                        'x-amz-credential': presignedData['x-amz-credential'],
                        'x-amz-date': presignedData['x-amz-date'],
                        'x-amz-signature': presignedData['x-amz-signature'],
                        'policy': presignedData['policy']
                    }).toString();


                    const fullUrl = `http://127.0.0.1:9000/demo/${encodeURIComponent(this.file.name)}?${urlParams}`;

                    $.ajax({
                        url: fullUrl,
                        type: "PUT",
                        data: this.file, // 直接上传文件对象
                        processData: false, // 不要处理数据
                        contentType: 'application/octet-stream', // 设置内容类型为二进制流
                        success: (response) => resolve(response),
                        error: (xhr, status, error) => reject(new Error("文件上传失败，请重试"))
                    });
                });
            }
        }
    });
</script>
</body>
</html>